package mymyoux.graphics.controls
{
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	import flash.utils.clearTimeout;
	import flash.utils.setTimeout;
	
	import mx.containers.Canvas;
	import mx.events.FlexEvent;
	import mx.events.ResizeEvent;
	
	import mymyoux.utils.Maths;
	public class GameMap extends Canvas
	{
		/**
		 * @private
		 */
		protected var _cheight:int;
		/**
		 * @private
		 */
		protected var _cwidth:int;
		/**
		 * @private
		 */		
		protected var _fheight:Number=0;
		/**
		 * @private
		 */
		protected var _fwidth:Number=0;
		/**
		 * @private
		 */		
		protected var _vheight:Number=0;
		/**
		 * @private
		 */
		protected var _vwidth:Number=0;
		/**
		 * @private
		 */
		 protected var _fixedSize:Boolean;
		 /**
		 * @private
		 */
		 protected var __calculating:Boolean=false;
		 /**
		 * @private
		 */
		 protected var _showSquares:Boolean;
		 /**
		 * @private
		 */
		 protected var _redrawBuffer:Number=-1;
		 /**
		 * @private
		 */
		 protected var _initX:int;
		 /**
		 * @private
		 */
		 protected var _initY:int;
		 /**
		 * Crée un plateau de jeu.
		 * @param cwidth Nombre de cases en largeur.
		 * @param cheight Nombre de cases en hauteur.
		 * @param width SI fixedSize=true ALORS width est la largeur d'une case SINON le nombre de cases visible en largeur.
		 * @param height SI fixedSize=true ALORS height est la hauteur d'une case SINON le nombre de cases visible en hauteur.
		 */
		public function GameMap(cwidth:int,cheight:int,width:Number=0,height:Number=0,fixedSize:Boolean=false)
		{
			
			_showSquares=true;
			_initX=0;
			_initY=0;
			this.cheight=cheight;
			this.cwidth=cwidth;
			this.fixedSize=fixedSize;
			if(fixedSize)
			{
				this.fheight=height;
				this.fwidth=width;
			}else
			{
				this.vheight=height;
				this.vwidth=width;
			}	
			
			this.addEventListener(ResizeEvent.RESIZE,calculateSize,false,0,true);
			this.addEventListener(FlexEvent.DATA_CHANGE,calculateSize,false,0,true);
			
			this.addEventListener(FlexEvent.CREATION_COMPLETE,onCreation,false,0,true);
			calculateSize();
		}
		protected function onCreation(event:FlexEvent):void
		{
			this.removeEventListener(FlexEvent.CREATION_COMPLETE,onCreation);
			this.setFocus();
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown,false,0,true);
		}
		/**
		 * Nombre de cases en hauteur.
		 */
		public function get cheight():int
		{
			return _cheight;
		}
		public function set cheight(value:int):void
		{
			_cheight=value;
		}
		 /**
		 * Nombre de cases en largeur.
		 */
		public function get cwidth():int
		{
			return _cwidth;
		}
		public function set cwidth(value:int):void
		{
			_cwidth=value;
		}
		 /**
		 * Hauteur d'une case.
		 */
		public function get fheight():Number
		{
			return _fheight;
		}
		public function set fheight(value:Number):void
		{
			_fheight=value>0?value:1;
			if(!__calculating)
			{
				calculateSize();
			}
		}
		/**
		 * Fixe la taille d'une case ou non.
		 */
		public function get fixedSize():Boolean
		{
			return _fixedSize;
		}
		public function set fixedSize(value:Boolean):void
		{
			_fixedSize=value;
			calculateSize();
		}
		 /**
		 * Largeur d'une case
		 */
		public function get fwidth():Number
		{
			return _fwidth;
		}
		public function set fwidth(value:Number):void
		{
			_fwidth=value>0?value:1;
			if(!__calculating)
			{
				calculateSize();
			}
		}
		/**
		 * Indique si l'ont doit voir le quadrillage ou non
		 */
		public function get showSquares():Boolean
		{
			return _showSquares;
		}
		public function set showSquares(value:Boolean):void
		{
			_showSquares=value;
		}
		/**
		 * Nombre de cases visibles en hauteur.
		 */
		public function get vheight():Number
		{
			return _vheight;
		}
		public function set vheight(value:Number):void
		{
			_vheight=value>0?Math.min(value,cheight):cheight;
			if(!__calculating)
			{
				calculateSize();
			}
		}
		/**
		 * Nombre de cases visibles en largeur
		 */
		public function get vwidth():Number
		{
			return _vwidth;
		}
		public function set vwidth(value:Number):void
		{
			_vwidth=value>0?Math.min(value,cwidth):cheight;
			if(!__calculating)
			{
				calculateSize();
			}
						
		}
		public override function get height():Number
		{
			return super.height;
		}
		public override function set height(value:Number):void
		{
			super.height=value;
			calculateSize();
		}
		public override function get width():Number
		{
			return super.width;
		}
		public override function set width(value:Number):void
		{
			super.width=value;
			calculateSize();
		}
		/**
		 * Recalcule les tailles en fonction du paramètre fixedSize
		 * et de la taille réel du composant.
		 * @param event Ignoré
		 */
		protected function calculateSize(event:Event=null):void
		{
			if(!__calculating)
			{
				//permet d'empêcher de créer une boucle
				__calculating=true;
				if(fixedSize)
				{
					vwidth=width/fwidth;
					vheight=height/fheight;
				}
				else
				{
					fwidth=width/vwidth;
					fheight=height/vheight;
				}
				__calculating=false;
				if(width>0 && height>0 && vwidth>0 && vheight>0)
				{
					redraw();
				}
						
			}
		}
		/**
		 * Redessine le plateau.
		 * Attention bufferisée!
		 */
		protected function redraw():void
		{
				flash.utils.clearTimeout(_redrawBuffer);
				_redrawBuffer=flash.utils.setTimeout(_redraw,100);
		}
		public function get initX():int
		{
			return _initX;
		}
		public function set initX(value:int):void
		{
			_initX=Maths.mod(value,cwidth);
			_redraw();
		}
		public function get initY():int
		{
			return _initY;
		}
		public function set initY(value:int):void
		{
			_initY=Maths.mod(value,cheight);
			_redraw();
		}
		protected function onKeyDown(event:KeyboardEvent):void
		{
			if(event.keyCode==Keyboard.LEFT)
			{
				initX-=Math.ceil(vwidth/100*20);
			}
			if(event.keyCode==Keyboard.RIGHT)
			{
				initX+=Math.ceil(vwidth/100*20);
			}
			if(event.keyCode==Keyboard.UP)
			{
				initY-=Math.ceil(vheight/100*20);
			}
			if(event.keyCode==Keyboard.DOWN)
			{
				initY+=Math.ceil(vheight/100*20);
			}
		}
		/**
		 * @private
		 */
		protected function _redraw():void
		{
			if(_showSquares)
			{
				this.graphics.clear();
				this.graphics.lineStyle(1,0x000000);
				
				var x:int,y:int;
				var count:Number=0;
			//	Timer.start(this);
				for(x=0;x<vwidth;x++)
				{
					for(y=0;y<vheight;y++)
					{
						count++;
						this.graphics.beginFill((x+initX)*(y+initY)*1000,1);
						this.graphics.drawRect(x*fwidth,y*fheight,fwidth,fheight);
						this.graphics.endFill();
					}
					
				}
				//Timer.stop(this);
			//	this.graphics.endFill();
			//	trace(count+" cases!");
				
			}
		}
	}
}